/***
* ==++==
*
* Copyright (c) Microsoft Corporation.  All rights reserved.
*
* ==--==
* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
*
* procdir.h
*
* C++ Actors: Directory
*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
****/

#pragma once

#include "actor_public.h"

namespace actors {
    
/// <summary>
/// The ProcessDirectory class defines the abstract interface of any implementation of
/// actor directories.
/// </summary>
class ProcessDirectory
{
public:
    /// <summary>
    /// Enter a new record into the actor directory.
    /// </summary>
    _DISPIMP virtual bool add_to_directory(const type_info &type, const std::string &address) { return false; }

    /// <summary>
    /// Remove an existing record from the actor directory.
    /// </summary>
    _DISPIMP virtual bool remove_from_directory(const type_info &type, const std::string &address) { return false; }

    /// <summary>
    /// Lookup locations where 'type' is hosted.
    /// </summary>
    _DISPIMP virtual bool Find(const type_info &type, std::vector<std::string> &locations) { return false; }

    /// <summary>
    /// Lookup the types hosted at the given address.
    /// </summary>
    _DISPIMP virtual bool Find(const std::string &address, type_info &type) { return false; }
};

/// <summary>
/// Remote directory implementation, based on sample directory service. Remote storage may be made redundant at the
/// client, by keeping more than one service URI in the storage implementation.
/// </summary>
class RemoteDirectory : public ProcessDirectory
{
public:
    RemoteDirectory(const std::string &uri) { AddStorageUri(uri); }
    RemoteDirectory(const std::vector<std::string> &uris)  { for (auto iter = uris.begin(); iter != uris.end(); iter++) AddStorageUri(*iter); }

    _DISPIMP ~RemoteDirectory();

    /// <summary>
    /// Add a storage service URI to the collection.
    /// </summary>
    _DISPIMP void AddStorageUri(const std::string &uri);

    /// <summary>
    /// Enter a new record into the actor directory.
    /// </summary>
    _DISPIMP virtual bool add_to_directory(const type_info &type, const std::string &address);

    /// <summary>
    /// Remove an existing record from the actor directory.
    /// </summary>
    _DISPIMP virtual bool remove_from_directory(const type_info &type, const std::string &address);

    /// <summary>
    /// Lookup locations where 'type' is hosted.
    /// </summary>
    _DISPIMP virtual bool Find(const type_info &type, std::vector<std::string> &locations);

    /// <summary>
    /// Lookup the types hosted at the given address.
    /// </summary>
    _DISPIMP virtual bool Find(const std::string &address, type_info &type);

private:
    std::vector<PID> m_storage;
};

} // namespace actors